package com.example.foo.api.web.member;

import java.util.List;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ruoyi.common.core.domain.AjaxResult;
import com.shitu.api.model.OpenAcctModel;
import com.example.support.wanquanpay.QueryMemberAcctStatusResponse;
import com.example.support.wanquanpay.WanquanBank;
import com.example.support.wanquanpay.WanquanPay;
import com.example.support.wanquanpay.WanquanPayException;
import com.example.support.wanquanpay.WanquanPayFileUtils;
import com.example.core.PageResult;
import com.example.core.Pageable;
import com.example.foo.api.boot.TokenHelper;
import com.example.foo.member.model.MemberBankcard;
import com.example.foo.member.model.MemberIdcard;
import com.example.foo.member.query.MemberBankcardQuery;
import com.example.foo.member.service.MemberBankcardService;
import com.example.foo.member.service.MemberIdcardService;

@org.springframework.web.bind.annotation.RestController
public class MemberBankcardAction {

	protected final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(getClass());

	private final MemberIdcardService memberIdcardService;
	private final MemberBankcardService memberBankcardService;
	private final WanquanPay wanquanPay;

	public MemberBankcardAction(MemberIdcardService memberIdcardService,
			MemberBankcardService memberBankcardService,
			WanquanPay wanquanPay) {
		this.memberIdcardService = memberIdcardService;
		this.memberBankcardService = memberBankcardService;
		this.wanquanPay = wanquanPay;
	}

	@GetMapping("/api/memberbankcards")
	public AjaxResult index(MemberBankcardQuery memberBankcardQuery, Pageable pageable) {
		Long userId = TokenHelper.verifyToken();
		if (!Objects.equals(userId, memberBankcardQuery.getUserId())) {
			return AjaxResult.error(403, "Access Forbidden");
		}
		acctStatus(userId);
		PageResult<MemberBankcard> pageResult = memberBankcardService.findMemberBankcards(memberBankcardQuery, pageable);
		return AjaxResult.successData(pageResult);
	}

	@GetMapping("/api/memberbankcards/{id}")
	public AjaxResult showMemberBankcard(@PathVariable("id") Long id) {
		Long userId = TokenHelper.verifyToken();
		MemberBankcard memberBankcard = memberBankcardService.findMemberBankcardById(id);
		if (memberBankcard == null) {
			return AjaxResult.error(404, "Not Found");
		}
		if (!Objects.equals(userId, memberBankcard.getUserId())) {
			return AjaxResult.error(403, "Access Forbidden");
		}
		return AjaxResult.successData(memberBankcard);
	}
   //开户并绑定银行卡
	@PostMapping("/api/memberbankcards")
	public AjaxResult createMemberBankcard(MemberBankcard memberBankcardForm) {
		AjaxResult validateError = validateForm(memberBankcardForm);
		if (validateError != null) {
			return validateError;
		}

		Long userId = TokenHelper.verifyToken();

		List<MemberBankcard> memberBankcards = memberBankcardService.findMemberBankcardsByUserId(userId);
		if (memberBankcards.size() > 0) {
			long count = memberBankcards.stream()
					.filter(memberBankcard -> memberBankcard.getType() == memberBankcardForm.getType())
					.count();
			if (count > 0) {
				return AjaxResult.error(400, "如果未绑定成功，返回上级修改信息再绑定，最多添加一个" + memberBankcardForm.getType().text);
			}
		}

		MemberIdcard memberIdcard = memberIdcardService.findMemberIdcardByUserId(userId);
		if (memberIdcard.getState() != MemberIdcard.State.success) {
			return AjaxResult.error(400, "请确认您的实名状态是否正常");
		}
		memberBankcardForm.setCardHolder(memberIdcard.getIdname());

		MemberBankcard memberBankcard = new MemberBankcard();
		memberBankcard.setType(memberBankcardForm.getType());
		memberBankcard.setState(MemberBankcard.State.pending);
		memberBankcard.setBankName(memberBankcardForm.getBankName());
		memberBankcard.setBankBranchName(memberBankcardForm.getBankBranchName());
		memberBankcard.setCardHolder(memberBankcardForm.getCardHolder());
		memberBankcard.setCardNumber(memberBankcardForm.getCardNumber());
		memberBankcard.setCardCellphone(memberBankcardForm.getCardCellphone());
		memberBankcard.setPicUrl(memberBankcardForm.getPicUrl());
		memberBankcard.setMemo("");
		memberBankcard.setUserId(userId);
		memberBankcardService.createMemberBankcard(memberBankcard);

		//
		AjaxResult openAcctError = openAcct(memberBankcard);
		if (openAcctError != null) {
			return openAcctError;
		}

		return AjaxResult.successMsg("已提交，请稍后查询绑定状态");
	}
   //修改绑定的银行卡
	@PutMapping("/api/memberbankcards/{id}")
	public AjaxResult updateMemberBankcard(@PathVariable("id") Long id, MemberBankcard memberBankcardForm) {
		AjaxResult validateError = validateForm(memberBankcardForm);
		if (validateError != null) {
			return validateError;
		}

		Long userId = TokenHelper.verifyToken();

		MemberBankcard memberBankcard = memberBankcardService.findMemberBankcardById(id);
		if (memberBankcard == null) {
			return AjaxResult.error(404, "Not Found");
		}
		if (!Objects.equals(userId, memberBankcard.getUserId())) {
			return AjaxResult.error(403, "Access Forbidden");
		}

		memberBankcard.setType(memberBankcardForm.getType());
		memberBankcard.setBankName(memberBankcardForm.getBankName());
		memberBankcard.setBankBranchName(memberBankcardForm.getBankBranchName());
		//memberBankcard.setCardHolder(memberBankcardForm.getCardHolder());
		memberBankcard.setCardNumber(memberBankcardForm.getCardNumber());
		memberBankcard.setCardCellphone(memberBankcardForm.getCardCellphone());
		memberBankcard.setPicUrl(memberBankcardForm.getPicUrl());
		memberBankcardService.updateMemberBankcard(memberBankcard);

		//
		AjaxResult openAcctError = openAcct(memberBankcard);
		if (openAcctError != null) {
			return openAcctError;
		}

		return AjaxResult.successMsg("已提交，请稍后查询绑定状态");
	}

	private void acctStatus(Long userId) {
		try {
			List<MemberBankcard> memberBankcards = memberBankcardService.findMemberBankcardsByUserId(userId);
			if (memberBankcards.isEmpty()) {
				return;
			}

			for (MemberBankcard memberBankcard : memberBankcards) {
				if (memberBankcard.getType() != MemberBankcard.Type.bankcard) {
					continue;
				}
				if (memberBankcard.getState() == MemberBankcard.State.success) {
					break;
				}

				MemberIdcard memberIdcard = memberIdcardService.findMemberIdcardByUserId(userId);
				String outerMemberId = memberIdcard.getOuterMemberId();

				QueryMemberAcctStatusResponse queryMemberAcctStatusResponse = wanquanPay.queryMemberAcctStatusByMemberId(outerMemberId);
				if (queryMemberAcctStatusResponse.isAcctStatusOk()) {
					memberBankcardService.updateMemberBankcardState(memberBankcard.getId(), MemberBankcard.State.success, "");
				} else {
					memberBankcardService.updateMemberBankcardState(memberBankcard.getId(), MemberBankcard.State.failure, queryMemberAcctStatusResponse.msg);
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}

	private AjaxResult openAcct(MemberBankcard memberBankcard) {
		if (memberBankcard.getType() == MemberBankcard.Type.bankcard) {
			Long userId = memberBankcard.getUserId();
			MemberIdcard memberIdcard = memberIdcardService.findMemberIdcardByUserId(userId);

			String memberId = memberIdcard.getOuterMemberId();
			String bankNo = WanquanBank.ofBankName(memberBankcard.getBankName()).bankNo;
			String cardNo = memberBankcard.getCardNumber();
			String bankPhone = memberBankcard.getCardCellphone();

			if (memberBankcard.getState() == MemberBankcard.State.pending
					|| memberBankcard.getState() == MemberBankcard.State.failure) {
				OpenAcctModel openAcctModel = OpenAcctModel.Builder.builder()
						.memberId(memberId)
						.validDateStart(memberIdcard.getStartDate())
						.validDateEnd(memberIdcard.getEndDate())
						.address(memberIdcard.getAddress())
						.bankNo(bankNo)
						.cardNo(cardNo)
						.bankPhone(bankPhone)
						.imgFace(WanquanPayFileUtils.copyURLToFile(memberBankcard.getPicUrl(), userId).getAbsolutePath())
						.build();
				try {
					//开户
					HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
					wanquanPay.openAcct(openAcctModel, request);


				} catch (WanquanPayException e) {
					return AjaxResult.error(500, e.getMessage());
				}
			}
			//绑定银行卡
			String phone = memberIdcard.getCellphone();
			try {
				wanquanPay.updateMemberBank(memberId, phone, bankNo, cardNo, bankPhone);
			} catch (WanquanPayException e) {
				return AjaxResult.error(500, e.getMessage());
			}

		} else if (memberBankcard.getType() == MemberBankcard.Type.alipay) {
			if (memberBankcard.getState() != MemberBankcard.State.success) {
				memberBankcardService.updateMemberBankcardState(memberBankcard.getId(), MemberBankcard.State.success, "");
			}
		} else {
			throw new IllegalStateException();
		}

		return null;
	}

	private AjaxResult validateForm(MemberBankcard memberBankcardForm) {
		if (memberBankcardForm.getType() == null) {
			return AjaxResult.error(400, "type must not be null");
		}
		if (StringUtils.isBlank(memberBankcardForm.getBankName())) {
			return AjaxResult.error(400, "bankName must not be null");
		}
		if (memberBankcardForm.getType() == MemberBankcard.Type.bankcard) {
			if (StringUtils.isBlank(memberBankcardForm.getBankBranchName())) {
				return AjaxResult.error(400, "bankBranchName must not be null");
			}
		}
		//if (StringUtils.isBlank(memberBankcardForm.getCardHolder())) {
		//	return AjaxResult.error(400, "cardHolder must not be null");
		//}
		if (StringUtils.isBlank(memberBankcardForm.getCardNumber())) {
			return AjaxResult.error(400, "cardNumber must not be null");
		}
		if (StringUtils.isBlank(memberBankcardForm.getCardCellphone())) {
			return AjaxResult.error(400, "cardCellphone must not be null");
		}
		if (StringUtils.isBlank(memberBankcardForm.getPicUrl())) {
			return AjaxResult.error(400, "picUrl must not be null");
		}
		return null;
	}

}
